package com.portal.tag;

import java.util.HashMap;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.ServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import com.portal.util.constants.TagConstants;

/**
 * The <CODE>defineObjects</CODE> tag will create the following variables in the JSP page:
 * <UL>
 * <LI><CODE>{@link RenderRequest} renderRequest</CODE>,
 * <LI><CODE>{@link ResourceRequest} resourceRequest</CODE>,
 * <LI><CODE>{@link ActionRequest} actionRequest</CODE>,
 * <LI><CODE>{@link EventRequest} eventRequest</CODE>,
 * <LI><CODE>{@link RenderResponse} renderResponse</CODE>,
 * <LI><CODE>{@link ResourceResponse} resourceResponse</CODE>,
 * <LI><CODE>{@link ActionResponse} actionResponse</CODE>,
 * <LI><CODE>{@link EventResponse} eventResponse</CODE>,
 * <LI><CODE>{@link PortletConfig} portletConfig</CODE>
 * <LI><CODE>{@link PortletSession} portletSession</CODE>,
 * <LI><CODE>{@link Map<String, Object>} portletSessionScope</CODE>,
 * <LI><CODE>{@link PortletPreferences} portletPreferences</CODE>,
 * <LI><CODE>{@link Map<String, String[]>} portletPreferencesValues</CODE>,
 * </UL>
 */
public class DefineObjectsTag extends TagSupport {

  /**
   * can be set only once
   * 
   * @param attribute - the attribute object to set
   * @param attributeName - the name of the attribute object
   * 
   * @return void
   */
  private void setAttribute(Object attribute, String attributeName) {
    if (pageContext.getAttribute(attributeName) == null) {
      pageContext.setAttribute(attributeName, attribute, PageContext.PAGE_SCOPE);
    }
  }

  private void setPortletRequestResponseAttribute(PortletRequest request, PortletResponse response) {

    String phase = (String) request.getAttribute(PortletRequest.LIFECYCLE_PHASE);

    // check where request and response where included from
    if (PortletRequest.ACTION_PHASE.equals(phase)) {
      setAttribute(request, "actionRequest");
      setAttribute(response, "actionResponse");
    } else if (PortletRequest.EVENT_PHASE.equals(phase)) {
      setAttribute(request, "eventRequest");
      setAttribute(response, "eventResponse");
    } else if (PortletRequest.RENDER_PHASE.equals(phase)) {
      setAttribute(request, "renderRequest");
      setAttribute(response, "renderResponse");
    } else if (PortletRequest.RESOURCE_PHASE.equals(phase)) {
      setAttribute(request, "resourceRequest");
      setAttribute(response, "resourceResponse");
    }
  }

  /**
   * Processes the <CODE>defineObjects</CODE> tag.
   * 
   * @return <CODE>SKIP_BODY</CODE>
   */
  public int doStartTag() throws JspException {
    
    ServletRequest servletRequest = pageContext.getRequest();
    PortletRequest portletRequest = (PortletRequest) servletRequest.getAttribute(TagConstants.PORTLET_REQUEST);
    PortletResponse portletResponse = (PortletResponse) servletRequest.getAttribute(TagConstants.PORTLET_RESPONSE);
    PortletConfig portletConfig = (PortletConfig) servletRequest.getAttribute(TagConstants.PORTLET_CONFIG);

    PortletSession portletSession = portletRequest.getPortletSession(false);
    Map<String, Object> portletSessionScope = portletSession == null ? new HashMap<String, Object>() : (Map<String, Object>) portletSession
        .getAttributeMap();

    PortletPreferences portletPreferences = portletRequest.getPreferences();
    Map<String, String[]> portletPreferencesValues = portletPreferences == null ? new HashMap<String, String[]>() : portletPreferences.getMap();

    setPortletRequestResponseAttribute(portletRequest, portletResponse);
    setAttribute(portletConfig, "portletConfig");
    setAttribute(portletSession, "portletSession");
    setAttribute(portletSessionScope, "portletSessionScope");
    setAttribute(portletPreferences, "portletPreferences");
    setAttribute(portletPreferencesValues, "portletPreferencesValues");

    return SKIP_BODY;
  }
 
/*  public int doEndTag() throws JspTagException {
    try {
        pageContext.getOut().write("Hello World!");
    }
    catch(java.io.IOException e) {
        throw new JspTagException("IO Error: " + e.getMessage());
    }
    return EVAL_PAGE;
}*/


}
